﻿using System;
using CodingDojo.Domain.KataAlarmClock;
using NUnit.Framework;

namespace CodingDojo.Domain.Test.KataAlarmClock
{
  [TestFixture]
  public class TestKataAlarmClock
  {
    private IAlarmsManager _alarmsManager;
    private Alarm _alarm;
    private Alarm _alarmTwo;

    [SetUp]
    public void Init()
    {
      _alarm = new Alarm(101, new TimeSpan(7, 0, 0), string.Empty);
      _alarmTwo = new Alarm(102, new TimeSpan(9, 0, 0), string.Empty);
      var repository = new AlarmRepository();
      repository.Add(_alarm);
      repository.Add(_alarmTwo);
      _alarmsManager = new AlarmsManager(repository);
    }

    [Test]
    public void Test_I_Have_To_Wake_Up_At_700()
    {
      _alarmsManager.TurnOn(_alarm.Id);
      var wakeUp = _alarmsManager.CheckAlarms(new TimeSpan(7, 0, 0));
      Assert.IsNotNull(wakeUp);
    }

    [Test]
    public void Test_I_Snooze_Until_709()
    {
      _alarmsManager.TurnOn(_alarm.Id);
      var wakeUp = _alarmsManager.CheckAlarms(new TimeSpan(7, 0, 0));
      Assert.IsNotNull(wakeUp);
      _alarmsManager.Snooze(_alarm.Id);
      wakeUp = _alarmsManager.CheckAlarms(new TimeSpan(7, 1, 0));
      Assert.IsNull(wakeUp);
      wakeUp = _alarmsManager.CheckAlarms(new TimeSpan(7, 9, 0));
      Assert.IsNotNull(wakeUp);
    }

    [Test]
    public void Test_I_Snooze_Until_718()
    {
      _alarmsManager.TurnOn(_alarm.Id);
      var wakeUp = _alarmsManager.CheckAlarms(new TimeSpan(7, 0, 0));
      Assert.IsNotNull(wakeUp);
      _alarmsManager.Snooze(_alarm.Id);
      wakeUp = _alarmsManager.CheckAlarms(new TimeSpan(7, 9, 0));
      Assert.IsNotNull(wakeUp);
      _alarmsManager.Snooze(_alarm.Id);
      wakeUp = _alarmsManager.CheckAlarms(new TimeSpan(7, 18, 0));
      Assert.IsNotNull(wakeUp);
    }

    [Test]
    public void Test_I_Snooze_Until_709_I_TurnOff_The_Alarm_And_I_Have_To_Wake_Up_At_900()
    {
      // arrange
      _alarmsManager.TurnOn(_alarm.Id);
      _alarmsManager.TurnOn(_alarmTwo.Id);
      // act
      var wakeUp = _alarmsManager.CheckAlarms(new TimeSpan(7, 0, 0));
      // assert
      Assert.IsNotNull(wakeUp);
      // act
      _alarmsManager.Snooze(_alarm.Id);
      wakeUp = _alarmsManager.CheckAlarms(new TimeSpan(7, 9, 0));
      // assert
      Assert.IsNotNull(wakeUp);
      // act
      _alarmsManager.TurnOff(_alarm.Id);
      wakeUp = _alarmsManager.CheckAlarms(new TimeSpan(9, 0, 0));
      // assert
      Assert.IsNotNull(wakeUp);
    }

    [Test]
    public void Test_I_Snooze_Until_718_And_The_Day_After_I_Woul_Like_To_Wake_Up_At_709()
    {
      // arrange
      _alarmsManager.TurnOn(_alarm.Id);
      _alarmsManager.Snooze(_alarm.Id);
      _alarmsManager.Snooze(_alarm.Id); // 718
      _alarmsManager.TurnOff(_alarm.Id);
      _alarmsManager.TurnOn(_alarm.Id);
      _alarmsManager.Snooze(_alarm.Id); // 709
      // act
      var wakeUp = _alarmsManager.CheckAlarms(new TimeSpan(7, 9, 0));
      // assert
      Assert.IsNotNull(wakeUp);
    }

    [Test]
    public void Test_All_Alarms_Are_Off()
    {
      var allOff = _alarmsManager.AllAlarmsOff;
      Assert.IsTrue(allOff);
    }  

    [Test]
    public void Test_The_Label_Of_The_1st_Alarm_Is_Wake_Up_Man()
    {
      const string message = "wake up man";
      _alarm.Label = message;
      _alarmsManager.TurnOn(_alarm.Id);
      var alarm = _alarmsManager.CheckAlarms(new TimeSpan(7, 0, 0));
      Assert.AreEqual(message, alarm.Label);
    }
  }
}
